#include "Command.h"

mini_engine::Command *mini_engine::Command::m_command = nullptr;
VkCommandPool mini_engine::Command::commandPool;
VkCommandBuffer mini_engine::Command::commandBuffer;

mini_engine::Command::Command()
{
}

void mini_engine::Command::createCommandPool()
{
    cout << "createCommandPool" << endl;
    QueueFamilyIndices queueFamilyIndices = QueueFamilies::getQueueFamilies()->findQueueFamilyIndices(PhysicalDevice::physicalDevice);

    VkCommandPoolCreateInfo poolInfo{};
    poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
    poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
    poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();

    if (vkCreateCommandPool(LogicalDevice::logicalDevice, &poolInfo, nullptr, &commandPool) != VK_SUCCESS)
    {
        throw std::runtime_error("failed to create command pool!");
    }
}

void mini_engine::Command::createCommandBuffer()
{
    VkCommandBufferAllocateInfo allocInfo{};
    allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
    allocInfo.commandPool = commandPool;
    allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    allocInfo.commandBufferCount = 1;

    if (vkAllocateCommandBuffers(LogicalDevice::logicalDevice, &allocInfo, &commandBuffer) != VK_SUCCESS)
    {
        throw std::runtime_error("failed to allocate command buffers!");
    }
}

mini_engine::Command *mini_engine::Command::getCommand()
{
    if (m_command == nullptr)
    {
        m_command = new Command();
        CommandPoolDestruction commandPoolDestruction;
    }
    return m_command;
}

mini_engine::Command::CommandPoolDestruction::~CommandPoolDestruction()
{
    if (m_command != nullptr)
    {
        delete m_command;
        m_command = nullptr;
    }
}

mini_engine::Command::~Command()
{
}